package com.aptemo.webetek.server;

import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import com.aptemo.webetek.client.commands.impl.GetStatisticsAction.EStatsPeriod;
import com.aptemo.webetek.client.enums.EnumEventStatus;
import com.aptemo.webetek.client.enums.EnumPickStatus;
import com.aptemo.webetek.client.enums.EnumBetStatus;
import com.aptemo.webetek.client.enums.EnumBetType;
import com.aptemo.webetek.server.data.Bet;
import com.aptemo.webetek.server.data.Pick;
import com.aptemo.webetek.server.data.Stake;
import com.aptemo.webetek.server.data.WebetekUser;
import com.aptemo.webetek.shared.StatisticsBean;
import com.aptemo.webetek.shared.StatisticsInterface;
import com.google.appengine.api.datastore.Key;

public class StatisticsUserEngine implements StatisticsInterface
{

	private EStatsPeriod		period;
	private String				userId;
	private WebetekUser			user;
	private CommonService		utils	= new CommonService();
	private PersistenceManager	persman;

	public StatisticsUserEngine(EStatsPeriod period, String userid)
	{
		this.period = period;
	}

	public StatisticsBean calculate(PersistenceManager pm, WebetekUser player)
	{
		// get the team...
		this.persman = pm;
		this.user = player;

		StatisticsBean stats = new StatisticsBean();

		int cntWon = 0;
		int cntPlaced = 0;
		int cntActiveBets = 0;
		int cntAllBets = 0;
		int cntAllStakes = 0;
		double sumEarnings = 0;
		double sumInvested = 0;

		// Query qearnings = persman.newQuery("select SUM(earnings) from " +
		// Stake.class.getName() + " where player == :p1 && status != :p2");
		// double earnings = (Double) qearnings.execute(user,
		// EnumStakeStatus.OPENED);
		// sumEarnings = earnings;

		// Query qstakes = persman.newQuery("select from " +
		// Stake.class.getName() + " where player == :p1 && status != :p2");
		// List<Stake> stakes = (List<Stake>) qstakes.execute(user,
		// EnumStakeStatus.OPENED);
		List<Stake> stakes = user.getStakes();

		for (Stake stake : stakes)
		{
			List<Key> pickkeys = stake.getPickKeys();
			cntPlaced += pickkeys.size();

			// Query qpicks = persman.newQuery("select from " +
			// Pick.class.getName() + " where :p1.contains(id)");
			// List<Pick> picks = (List<Pick>) qpicks.execute(pickkeys);

			// Query qcountpicks = persman.newQuery("select COUNT(id) from " +
			// Pick.class.getName() +
			// " where :p1.contains(id) && status == :p2");
			// int won = (Integer) qcountpicks.execute(pickkeys,
			// EnumPickStatus.WON);
			// cntWon += won;
			Query qcountpicks = persman.newQuery("select id from " + Pick.class.getName() + " where :p1.contains(id) && status == :p2");
			List<Key> keys = (List<Key>) qcountpicks.execute(pickkeys, EnumPickStatus.WON);
			cntWon += keys.size();

			// active
			// Query qcountbets = persman.newQuery("select COUNT(id) from " +
			// Bet.class.getName() + " where :p1.contains(picks)");
			// int active = (Integer) qcountpicks.execute(stake.getPickKeys());
			// cntActiveBets += active;

			sumEarnings += stake.getEarnings();
			if (stake.getBetType() == EnumBetType.SINGLE)
			{
				sumInvested += stake.getAmount() * pickkeys.size();
			}

			// List<Key> pickkeys = stake.getPickKeys();
			// int noOfpicks = pickkeys.size();
			// for (Key key : pickkeys)
			// {
			// Pick pick = persman.getObjectById(Pick.class, key);
			// if (pick.getStatus() == EnumPickStatus.WON)
			// {
			// cntWon++;
			// }
			// Bet bet = pick.getBet();
			// if (bet.getStatus() == EnumBetStatus.ACTIVE)
			// {
			// cntActiveBets++;
			// }
			// cntPlaced++;
			//
			// sumEarnings += stake.getEarnings();
			// if (stake.getBetType() == EnumStakeType.SINGLE)
			// {
			// sumInvested += stake.getAmount() * noOfpicks;
			// }
			// }
			if (stake.getBetType() == EnumBetType.SINGLE)
			{
				cntAllBets += pickkeys.size();
			}
			else
			{
				cntAllBets++;
			}
			cntAllStakes++;
		}

		// for (Stake stake : stakes)
		// {
		//
		// if (stake.getStatus() != EnumStakeStatus.OPENED)
		// {
		// Query q = persman.newQuery("select pickKeys from " +
		// Stake.class.getName() + " where player == :p1");
		// List<List<Key>> result = (List<List<Key>>) q.execute(user);
		// if (result.iterator().hasNext() == false)
		// {
		// continue;
		// }
		// // List<Key> pickkeys = result.get(0);
		//
		// List<Key> pickkeys = stake.getPickKeys();
		// int noOfpicks = pickkeys.size();// stake.getPickKeys().size();
		// for (Key key : pickkeys)
		// {
		// Pick pick = persman.getObjectById(Pick.class, key);
		// if (pick.getStatus() == EnumPickStatus.WON)
		// {
		// cntWon++;
		// }
		// Bet bet = pick.getBet();
		// if (bet.getStatus() == EnumBetStatus.ACTIVE)
		// {
		// cntActiveBets++;
		// }
		// cntPlaced++;
		// }
		// sumEarnings += stake.getEarnings();
		// if (stake.getBetType() == EnumStakeType.SINGLE)
		// {
		// sumInvested += stake.getAmount() * noOfpicks;
		// }
		// }
		// if (stake.getBetType() == EnumStakeType.SINGLE)
		// {
		// cntAllBets += stake.getPickKeys().size();
		// }
		// else
		// {
		// cntAllBets++;
		// }
		// cntAllStakes++;
		// }

		stats.setNoOfUsers(1);
		stats.setNoOfBetsPlaced(cntPlaced);
		stats.setNoOfBetsWon(cntWon);
		stats.setNoOfActiveBets(cntActiveBets);
		stats.setEarnings(sumEarnings);
		stats.setAmountInvested(sumInvested);
		stats.setNoOfAllBets(cntAllBets);
		// stats.setNoOfAllStakes(cntAllStakes);

		// stats.setNoOfUsers(getNoOfUsers());
		// stats.setNoOfTeams(getNoOfTeams());
		// stats.setNoOfAllStakes(getNoOfAllStakes());
		// stats.setAmountGained(getAmountGained());
		// stats.setNoOfOpenedStakes(getNoOfOpenedStakes());
		//
		// stats.setNoOfActiveBets(getNoOfActiveBets());
		// stats.setNoOfBetsPlaced(getNoOfBetsPlaced());
		// stats.setNoOfBetsWon(getNoOfBetsWon());
		// // !!!! specifics for user...
		// stats.setNoOfAllBets(getNoOfAllBets());
		// stats.setEarnings(getEarnings());
		// stats.setAmountInvested(getAmountInvested());

		return stats;
	}

	@Override
	public double getEarnings()
	{
		double sum = 0;
		int cnt = 0;
		List<Stake> stakes = user.getStakes();
		for (Stake stake : stakes)
		{
			if (stake.getStatus() == EnumBetStatus.CLOSED)
			{
				sum += stake.getEarnings();
			}
		}
		return sum;
	}

	@Override
	public double getAmountInvested()
	{
		int cnt = 0;
		double sum = 0.0;
		List<Stake> stakes = user.getStakes();
		for (Stake stake : stakes)
		{
			// if (stake.getStatus() != EnumStakeStatus.OPENED)
			{
				sum += stake.getAmount();
			}
		}
		return sum;
	}

	@Override
	public int getNoOfActiveBets()
	{
		int cnt = 0;
		List<Stake> stakes = user.getStakes();
		for (Stake stake : stakes)
		{
			if (stake.getStatus() != EnumBetStatus.OPENED)
			{
				for (Key key : stake.getPickKeys())
				{
					Pick pick = persman.getObjectById(Pick.class, key);
					Bet bet = pick.getParent(persman);
					if (bet.getStatus() == EnumEventStatus.ACTIVE)
					{
						cnt++;
					}

				}
			}
		}
		return cnt;
	}

	@Override
	public int getNoOfAllBets()
	{
		int cnt = 0;
		List<Stake> stakes = user.getStakes();
		for (Stake stake : stakes)
		{
			// if (stake.getStatus() != EnumStakeStatus.OPENED)
			{
				cnt += stake.getPickKeys().size();
				// for (Key key : stake.getPickKeys())
				// {
				// // Pick pick = pm.getObjectById(Pick.class, key);
				// cnt++;
				// }
			}
		}
		return cnt;
	}

	@Override
	public int getNoOfBetsWon()
	{
		int cnt = 0;
		List<Stake> stakes = user.getStakes();
		for (Stake stake : stakes)
		{
			if (stake.getStatus() != EnumBetStatus.OPENED)
			{
				for (Key key : stake.getPickKeys())
				{
					Pick pick = persman.getObjectById(Pick.class, key);
					if (pick.getStatus() == EnumPickStatus.WON)
					{
						cnt++;
					}
				}
			}
		}
		return cnt;
	}

	@Override
	public int getNoOfBetsPlaced()
	{
		int cnt = 0;
		List<Stake> stakes = user.getStakes();
		for (Stake stake : stakes)
		{
			if (stake.getStatus() != EnumBetStatus.OPENED)
			{
				cnt += stake.getPickKeys().size();
				// for (Key key : stake.getPickKeys())
				// {
				// // Pick pick = pm.getObjectById(Pick.class, key);
				// cnt++;
				// }
			}
		}
		return cnt;
	}

	@Override
	public int getNoOfTeams()
	{
		List<WebetekUser> users = utils.getUser(persman, user.getEmail());
		if (users == null)
		{
			return 0;
		}
		return users.size();
	}

	@Override
	public int getNoOfUsers()
	{
		return 1;
	}

	// @Override
	// public int getNoOfAllStakes()
	// {
	// return user.getStakes().size();
	// }
	//
	// @Override
	// public int getNoOfOpenedStakes()
	// {
	// int cnt = 0;
	// List<Stake> stakes = user.getStakes();
	// for (Stake stake : stakes)
	// {
	// if (stake.getStatus() == EnumStakeStatus.OPENED)
	// {
	// cnt++;
	// }
	// }
	// return cnt;
	// }

	@Override
	public Double getAmountGained()
	{
		Double sum = 0.0;
		List<Stake> stakes = user.getStakes();
		for (Stake stake : stakes)
		{
			sum += stake.getEarnings();
		}
		return sum;
	}

}
